const protobufjs = require('protobufjs');
const util = require('node:util');
const zlib = require('node:zlib');
const unzip = util.promisify(zlib.unzip);

// Import the TikTok schema and utilities
const tikTokSchema = require('./dist/types/tiktok-schema');
const utilities = require('./dist/lib/utilities');
const { deserializeMessage, deserializeWebSocketMessage } = utilities;
// 引入WebSocket服务器模块
const { broadcastMessage } = require('../websocket/websocket-server.js');


/*
protobuf数据解析相关
*/
let douyinSchemaPath = require.resolve('./proto/tiktok.proto');
let douyinSchema = null;

//进行pb数据解析
function loadDouyinSchema() {
    if (!douyinSchema) {
        douyinSchema = protobufjs.loadSync(douyinSchemaPath);
        console.log("🟢加载protobuf成功");
    }
}
function deserializeMessage1(protoName, binaryMessage) {
    loadDouyinSchema();
    try {
        var webcastData = douyinSchema.lookupType(`TikTok.${protoName}`).decode(binaryMessage);
        return webcastData;
    } catch (error) {
        //console.error("消息解析失败", error);
        return;
    }
}
async function pb2json(pbData) {
    try {
        let decodedWebsocketMessage = deserializeMessage1('WebcastWebsocketMessage', pbData);
        if (decodedWebsocketMessage.type === 'msg') {
            let binary = decodedWebsocketMessage.binary;
            if (binary && binary.length > 2 && binary[0] === 0x1f && binary[1] === 0x8b && binary[2] === 0x08) {
                pbData = await unzip(binary);
            }
            let Response = deserializeMessage('ProtoMessageFetchResult', pbData);

            if (Response && Response.messages && Response.messages.length > 0) {
                Response.messages.forEach(element => {
                    // 公共部分
                    let msgId = element.msgId;
                    let data = null;
                    let type = null;
                    let schemeType = null;
                    switch (element.type) {
                        case 'WebcastLikeMessage':
                            schemeType = 'WebcastLikeMessage'
                            type = "点赞"
                            break;
                        case 'WebcastChatMessage':
                            schemeType = 'WebcastChatMessage'
                            type = '弹幕'
                            break;
                        case 'WebcastMemberMessage':
                            schemeType = 'WebcastMemberMessage'
                            type = '进房'
                            break;
                        case 'WebcastGiftMessage':
                            schemeType = 'WebcastGiftMessage'
                            type = '礼物'
                            break;
                        case 'WebcastSocialMessage':
                            schemeType = 'WebcastSocialMessage'
                            type = '关注/分享'//action = 3 分享    action = 1 关注
                            break;
                        case 'WebcastRoomMessage':
                            schemeType = 'WebcastRoomMessage'
                            type = '房间消息'
                            break;
                        case 'WebcastRoomUserSeqMessage':
                            schemeType = 'WebcastRoomUserSeqMessage'
                            type = '房间用户序列消息'
                            break;
                        default:
                            schemeType = element.method
                            type = null
                    }

                    if (type == null) {
                        //console.log("🔴未知", element.type);
                    } else {
                        if (schemeType) {
                            data = deserializeMessage(schemeType, element.payload)
                            if (type == "关注/分享") {
                                if (data.action == 3) {
                                    type = "分享"
                                }
                                if (data.action == 1) {
                                    type = "关注"
                                }
                            }
                            //console.log("🟢成功", type, schemeType);
                            handleData(type, data)
                        } else {
                            //console.log("🔵已知", type, element.method)
                        }
                    }
                });

            }

        }

    } catch (err) {
        //console.log("消息解码失败", err);
    }
}

// 转换Long对象为字符串的函数
function convertLongToString(value) {
    if (value && typeof value === 'object' && value.hasOwnProperty('low') && value.hasOwnProperty('high')) {
        // 处理Long类型对象，转换为字符串
        if (value.high === 0) {
            // 如果high为0，直接返回low的值
            return parseInt(value.low.toString());
        } else {
            // 如果high不为0，需要计算完整的64位值
            const longValue = value.high * 0x100000000 + (value.low >>> 0);
            return parseInt(longValue.toString());
        }
    }
    return parseInt(value);
}

// 递归转换对象中的所有Long类型字段
function convertLongFields(obj) {
    if (obj === null || obj === undefined) {
        return obj;
    }

    if (Array.isArray(obj)) {
        return obj.map(item => convertLongFields(item));
    }

    if (typeof obj === 'object') {
        // 检查是否是Long对象
        if (obj.hasOwnProperty('low') && obj.hasOwnProperty('high') && obj.hasOwnProperty('unsigned')) {
            return convertLongToString(obj);
        }

        // 递归处理对象的所有属性
        const converted = {};
        for (const key in obj) {
            if (obj.hasOwnProperty(key)) {
                converted[key] = convertLongFields(obj[key]);
            }
        }
        return converted;
    }

    return obj;
}


function handleData(type, data) {
    // 处理数据
    let msg = {}
    if (!data || !data.user) {
        return;
    }
    msg.uid = data.user.userId;
    msg.secUid = data.user.secUid;
    msg.name = data.user.nickname;
    msg.sex = 1;//data.user.gender;//TK缺少这个字段
    msg.level = 0;//data.user.Level;//TK缺少这个字段
    msg.payGrade = data.user.PayGrade ? data.user.PayGrade.level : 0;
    msg.avatar = data.user.profilePicture ? data.user.profilePicture.url[0] : '';
    msg.msgId = data.common.msgId;
    msg.msgType = type;

    if (type == "点赞") {
        msg.newType = "👍"
        msg.count = data.likeCount;
    }
    if (type == "进房") {
        msg.newType = "🚪"
        msg.action = data.action;
        msg.memberCount = data.memberCount;
    }
    if (type == "关注") {
        msg.newType = "💗"
        msg.followCount = data.followCount;
    }
    if (type == "分享") {
        msg.newType = "✈️"
        msg.shareType = data.shareType;
    }
    if (type == "弹幕") {
        msg.newType = "💬"
        msg.content = data.comment;
    }
    if (type == "礼物") {
        msg.newType = "🎁"
        msg.giftId = data.giftDetails.id;
        msg.giftName = data.giftDetails.giftName;
        msg.comboCount = data.comboCount;//礼物数量
        msg.repeatCount = data.repeatCount;
        msg.groupId = data.groupId;//组刷ID
        msg.groupCount = data.groupCount;//组刷数量
        msg.diamondCount = data.giftDetails.diamondCount;//礼物单价
        msg.giftCount = computedGiftNum(msg);//修正后的礼物数量
    }
    if (type == "粉丝团") {
        msg.newType = "👥"
        msg.content = data.content;// "恭喜 xxx 成为成员"
        msg.type = data.type;
    }

    sendMessage(JSON.stringify(convertLongFields(msg)))
}


function sendMessage(message) {
    // 将弹幕消息广播给所有WebSocket客户端
    try {
        const clientCount = broadcastMessage(message);
        //console.log(`弹幕消息已广播给 ${clientCount} 个WebSocket客户端:`, message);
    } catch (error) {
        //console.error('广播弹幕消息失败:', error);
    }
}

// 计算礼物数量
const filterGift = {}
function computedGiftNum(data) {
    const tempId = `${data.uid}_${data.giftId}_${data.groupId}`

    // 第一种情况--高价礼物单点
    if (data.groupId == '0') {
        return data.repeatCount
    }
    if (filterGift[tempId]) {
        // 之前记录的比这次大，返回0
        if (data.repeatCount <= filterGift[tempId]) {
            filterGift[tempId] = data.repeatCount
            return 0
        }
        // 之前记录过，求差
        const count = data.repeatCount - filterGift[tempId]
        filterGift[tempId] = data.repeatCount
        return count
    }
    // 之前没记录过，取值
    filterGift[tempId] = data.repeatCount
    return data.repeatCount
}



module.exports = {
    pb2json,
};